package org.elkastud.fasta;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import org.elkastud.model.MatchResult3;
import org.elkastud.util.PrintComparator;

/**
 * Read DNA sequence and write compare results to file
 * @author Mariusz Jasiński
 */
public class FastaIO {

    /**
     * new sequence mark
     */
    private static final String NEW_SEQ_MARK = ">";
    
    /**
     * @param file File to read
     * @return List od sequence obiects
     * @throws FileNotFoundException if file does not exist
     * @throws IOException if file object is not file
     */
    public static List<FastaSequence> readFile(File file){
        List<FastaSequence> seqList = new ArrayList<FastaSequence>();
        try {
            BufferedReader reader = new BufferedReader(new FileReader(file));
            String name = null;
            String description = null;
            StringBuilder sequence = new StringBuilder();
            while (reader.ready()) {
                String line = reader.readLine();
                if (line.startsWith(NEW_SEQ_MARK)) {
                    if (name != null) {
                        seqList.add(new FastaSequence(name, description, sequence.toString()));
                    }
                    name = getSeqName(line);
                    description = getSeqDescription(line);
                    sequence = new StringBuilder();
                } else if (!"".equals(line)) {
                    sequence.append(line);
                }
            }
            if (name != null && sequence.length() > 0) {
                seqList.add(new FastaSequence(name, description, sequence.toString()));
            }
            reader.close();
        }
        catch (FileNotFoundException e) {
            // plik podany z FileChoosera - na pewno istnieje
        } catch (IOException e) {
            
        }
        return seqList;
    }

    /**
     * Save match result into file
     * @param file file to save
     * @param output list of results
     * @throws IOException where save is not possible
     * @throws Exception where file is null or results list is null
     */
    public static void saveFile(File file, List<MatchResult3> output) throws IOException, Exception{
        if (output == null || file == null) {
            throw new Exception("Nothing to save.");
        }
        BufferedWriter writer = new BufferedWriter(new FileWriter(file));

        for (MatchResult3 res : output) {
            StringBuilder builder = new StringBuilder();

            builder.append(NEW_SEQ_MARK);
            builder.append(System.lineSeparator());

            String text = PrintComparator.getColoredSeq(res.getSequenceA(), false);
            builder.append(text);
            builder.append(System.lineSeparator());

            text = PrintComparator.compareSequences(res.getSequenceA(), res.getSequenceB(), false);
            builder.append(text);
            builder.append(System.lineSeparator());

            text = PrintComparator.getColoredSeq(res.getSequenceB(), false);
            builder.append(text);
            builder.append(System.lineSeparator());

            text = PrintComparator.compareSequences(res.getSequenceB(), res.getSequenceC(), false);
            builder.append(text);
            builder.append(System.lineSeparator());

            text = PrintComparator.getColoredSeq(res.getSequenceC(), false);
            builder.append(text);
            builder.append(System.lineSeparator());

            builder.append(System.lineSeparator());

            writer.write(builder.toString());
        }

        writer.close();
    }

    /**
     *
     * @param line line with sequence description
     * @return Sequence name or null if is empty
     */
    private static String getSeqName(String line) {
        if (line == null || "".equals(line) || !line.startsWith(NEW_SEQ_MARK)) {
            return null;
        }
        int index = whiteSpaceIndex(line);
        if (index != -1) {
            return line.substring(0, index);
        }
        return line;
    }

    /**
     *
     * @param line line with sequence description
     * @return sequence description or null if is empty
     */
    private static String getSeqDescription(String line) {
        if (line == null || "".equals(line) || !line.startsWith(NEW_SEQ_MARK)) {
            return null;
        }
        int index = whiteSpaceIndex(line);
        if (index > 0) {
            return line.substring(index + 1);
        }
        return null;
    }

    /**
     *
     * @param line of text file
     * @return first index of white space in line or -1 if line does not contains any white character
     */
    private static int whiteSpaceIndex(String line) {
        if (line != null) {
            for (int i=0; i<line.length(); ++i) {
                if (Character.isWhitespace(line.charAt(i))) {
                    return i;
                }
            }
        }
        return -1;
    }
}
